﻿using System;
using System.Collections.Generic;
using System.Windows.Media.Media3D;
using LFSRecord2.Misc;

namespace LFSRecord2.Model
{
    public class CompLayerFreeCamera : CompLayerBase
    {
        public enum PropertyTypes
        {
            Position = 0,
            Orientation = 1,
            Heading = 2,
            Pitch = 3,
            Roll = 4,
            Fov = 5,
        }

        [Flags]
        public enum PropertyTypesFlags
        {
            None = 0,
            Position = 1,
            Orientation = 2,
            Heading = 4,
            Pitch = 8,
            Roll = 16,
            Fov = 32,
        }

        public CompLayerFreeCamera(short layerIndex, string layerName)
        {
            UniqueID = MathHelper.UniqueID;
            LayerIndex = layerIndex;
            LayerType = CompLayerTypes.FreeCamera;
            LayerName = layerName;
            LayerObjectMesh = new CompLayerCameraMesh();

            IsActiveCamera = false;

            // Setup properties
            Properties = new List<CompLayerPropertyBase>(5);
            Properties.Add(new CompLayerPropertyPoint3D(this, 0, "Position", new Point3D(0, 0, 20), LayerPropertyValueMeaning.Generic, true));
            Properties.Add(new CompLayerPropertyPoint3D(this, 1, "Orientation", new Point3D(0, 0, 0), LayerPropertyValueMeaning.Degrees, false));
            Properties.Add(new CompLayerPropertyDouble(this, 2, "Heading", 0, LayerPropertyValueMeaning.Degrees));
            Properties.Add(new CompLayerPropertyDouble(this, 3, "Pitch", 0, LayerPropertyValueMeaning.Degrees));
            Properties.Add(new CompLayerPropertyDouble(this, 4, "Roll", 0, LayerPropertyValueMeaning.Degrees));
            Properties.Add(new CompLayerPropertyDouble(this, 5, "FOV", 60, LayerPropertyValueMeaning.Generic));

            ((CompLayerPropertyDouble)Properties[(int)PropertyTypes.Fov]).MinValue = 10;
            ((CompLayerPropertyDouble)Properties[(int)PropertyTypes.Fov]).MaxValue = 120;

            SetCurrentTransformMatrix();
        }

        public override Matrix3D GetTransformMatrixAtFrame(int frame)
        {
            // Orientate
            Matrix3D mTr = new Matrix3D();
            Point3D orientation = (Point3D)((CompLayerPropertyPoint3D)Properties[(int)PropertyTypes.Orientation]).GetValueAtFrame(frame);

            mTr.Rotate(new Quaternion(new Vector3D(0, 1, 0), orientation.Y));
            mTr.Rotate(new Quaternion(new Vector3D(0, 0, 1), orientation.Z));
            mTr.Rotate(new Quaternion(new Vector3D(1, 0, 0), orientation.X));

            // Look at rotation
            mTr.Rotate(new Quaternion(new Vector3D(0, 1, 0), (double)((CompLayerPropertyDouble)Properties[(int)PropertyTypes.Roll]).GetValueAtFrame(frame)));
            mTr.Rotate(new Quaternion(new Vector3D(1, 0, 0), (double)((CompLayerPropertyDouble)Properties[(int)PropertyTypes.Pitch]).GetValueAtFrame(frame)));
            mTr.Rotate(new Quaternion(new Vector3D(0, 0, 1), (double)((CompLayerPropertyDouble)Properties[(int)PropertyTypes.Heading]).GetValueAtFrame(frame)));

            // Translate the matrix
            Point3D pos = (Point3D)((CompLayerPropertyPoint3D)Properties[(int)PropertyTypes.Position]).GetValueAtFrame(frame);
            mTr.Translate(new Vector3D(pos.X, pos.Y, pos.Z));

            return mTr;
        }

        public override void SetMeshLookAtPointAtFrame(int frame)
        {
        }

        public override void SetMeshCenterPointAtFrame(int frame)
        {
        }

        public override void RemoveParentingJump(CompLayerBase parentLayer)
        {
        }

        public override void AddParentingJump()
        {
        }
    }
}
